package com.mlnx.netty.handler;


import com.mlnx.bptp.BpPacket;
import com.mlnx.tp.base.utils.LogUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.ReferenceCountUtil;

import java.util.List;


public class BpDecode extends ByteToMessageDecoder {

    enum State {
        HEAD, LEN, CONTANT
    }

    private State state = State.HEAD;


    private int length;

    @Override
    public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
            throws Exception {
        while (true) {
            switch (state) {
                case HEAD:
                    if (matchHead(in)) {

                        state = State.LEN;

                    } else {
                        return;
                    }
                case LEN:
                    if (in.isReadable()) {


                        length = 0x000000ff & in.readByte();

                        state = State.CONTANT;

                    } else {
                        return;
                    }
                case CONTANT:
                    if (in.isReadable(length - 2)) {

                        ByteBuf frame = null;
                        try {
                            frame = in.readBytes(length - 2);
                            BpPacket bpPacket = new BpPacket();
                            bpPacket.decode(frame.nioBuffer());
                            out.add(bpPacket);
                        } catch (Exception e) {
                            LogUtils.e("receive Exception:", e);
                        } finally {
                            ReferenceCountUtil.release(frame);
                            state = State.HEAD;
                        }
                    } else {
                        return;
                    }
            }
        }

    }

    private boolean matchHead(ByteBuf buf) {

        while (buf.isReadable()) {
            byte b = buf.readByte();

            if (b == (byte) 0xFA) {

                return true;
            }
        }
        return false;
    }


}
